/*
 * Copyright 2010-2011 Mike Novak <michael.novakjr@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.codeversed.plugins.buzz.activity;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.codeversed.plugins.buzz.R;
import com.codeversed.plugins.buzz.util.Constants;
import com.codeversed.plugins.buzz.util.BuzzUtils;
import com.codeversed.plugins.buzz.util.HttpUtils;
import com.codeversed.plugins.buzz.util.ImageUtils;
import com.codeversed.plugins.buzz.widget.GalleryAdapter;
import com.codeversed.plugins.buzz.widget.LocationOverlay;

public class BuzzDetailActivity extends MapActivity {
    protected static final int DIALOG_COMMENT = 0x1;
    protected static final int DIALOG_POST_COMMENT = 0x2;
    protected static final int DIALOG_COMMENT_ERROR = 0x3;
    protected static final int DIALOG_NO_NETWORK = 0x4;
    protected static final int DIALOG_EMPTY_COMMENT = 0x5;
    protected static final int DIALOG_RESHARE_NOTE = 0x6;
    protected static final int DIALOG_POST_RESHARE = 0x7;
    protected static final int DIALOG_RESHARE_ERROR = 0x8;
    
    private String mToken;
    private String mTokenSecret;
    private String mActivityId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_buzzdetail);
        
        ImageView avatarView = (ImageView) findViewById(R.id.detail_avatar_view);
        Gallery galleryView = (Gallery) findViewById(R.id.detail_preview_gallery);
        MapView mapView = (MapView) findViewById(R.id.location_map_view);
        TextView actorView = (TextView) findViewById(R.id.detail_actor_view);
        TextView postdateView = (TextView) findViewById(R.id.detail_postdate_view);
        TextView sourceView = (TextView) findViewById(R.id.detail_source_view);
        TextView contentView = (TextView) findViewById(R.id.detail_content_text);
        TextView locationLabel = (TextView) findViewById(R.id.location_text_label);
        TextView locationText = (TextView) findViewById(R.id.location_text_view);
        View galleryHolder = findViewById(R.id.gallery_holder);
        Button commentsBtn = (Button) findViewById(R.id.comments_view_button);

        /* pull cached content from the intent. */
        Intent intent = getIntent();
        mActivityId = intent.getStringExtra("id");
        String title = intent.getStringExtra("title");
        String avatar = intent.getStringExtra("avatar");
        String actor = intent.getStringExtra("actor");
        String content = intent.getStringExtra("content");
        String source = intent.getStringExtra("source");
        String geocode = intent.getStringExtra("geocode");
        String address = intent.getStringExtra("address");
        String commentCount = intent.getStringExtra("comment_count");
        
        final String[] photos = intent.getExtras().getStringArray("photos");
        final String[] images = intent.getExtras().getStringArray("full_photos");

        long pubStamp = intent.getLongExtra("published", System.currentTimeMillis());

        if (actor != null) {
            actorView.setText(actor);
        }
        
        if (content != null) {
            contentView.setText(Html.fromHtml(content));
        }
        
        if (source != null) {
            sourceView.setText("Source: " + source);
        }
        
        if (geocode != null) {
            String[] coords = geocode.split(" ");
            
            GeoPoint pt = new GeoPoint((int) (Double.valueOf(coords[0]) * 1E6), (int) (Double.valueOf(coords[1]) * 1E6));
            LocationOverlay overlay = new LocationOverlay(new BitmapDrawable(
                    BitmapFactory.decodeResource(getResources(), R.drawable.ic_location_pin)));
            OverlayItem pin = new OverlayItem(pt, "Checkin", content);
            overlay.addOverlay(pin);
            
            mapView.setVisibility(MapView.VISIBLE);
            mapView.getOverlays().add(overlay);
            mapView.preLoad();
            mapView.displayZoomControls(false);
            mapView.setBuiltInZoomControls(false);
            mapView.getController().setCenter(pt);
            mapView.getController().animateTo(pt);
            mapView.getController().setZoom((int) (mapView.getMaxZoomLevel() * 0.65));
            mapView.invalidate();
        }
        
        if (address != null) {
            locationLabel.setVisibility(TextView.VISIBLE);
            locationText.setVisibility(TextView.VISIBLE);
            locationText.setText(address);
        }
                
        if (photos != null) {                        
            GalleryDownloadTask task = new GalleryDownloadTask(galleryView, galleryHolder);
            task.execute(photos);
            
            galleryView.setOnItemClickListener(new Gallery.OnItemClickListener() {
                public void onItemClick(AdapterView parent, View v, int position, long id) {
                    Intent intent = new Intent(v.getContext(), PhotoViewActivity.class);

                    if (images != null) {
                        intent.setData(Uri.parse(images[position]));
                    } else {
                        intent.setData(Uri.parse(photos[position]));
                    }
                    
                    startActivity(intent);
                }
            });
        }
        
        SimpleDateFormat format = new SimpleDateFormat("MMMM dd, yyyy h:mm a");
        postdateView.setText("Posted on: " + format.format(new Date(pubStamp)));
        
        Bitmap avatarImage = ImageUtils.roundBitmapCorners(getResources(), R.drawable.ic_blank_avatar, 15);
        avatarView.setImageBitmap(avatarImage);
        
        if (avatar != null) {
            ImageDownloadTask task = new ImageDownloadTask(avatarView);
            task.execute(avatar);
        }
        
        SharedPreferences prefs = getSharedPreferences("buzz_oauth.prefs", Context.MODE_PRIVATE);
        mToken = prefs.getString(Constants.PREF_TOKEN, "");
        mTokenSecret = prefs.getString(Constants.PREF_TOKEN_SECRET, "");
        
        if (mActivityId != null) {
            
        }
    }
    
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
    
    @Override
    protected Dialog onCreateDialog(int id, Bundle args) {
        AlertDialog.Builder builder;
        
        switch (id) {
        case DIALOG_COMMENT:
            builder = new AlertDialog.Builder(this);
            builder.setTitle(getString(R.string.dialog_comment_title));
            
            View view = getLayoutInflater().inflate(R.layout.dialog_comment, null, false);
            builder.setView(view);
            
            DialogInterface.OnClickListener dialogListener = new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    switch (which) {
                    case DialogInterface.BUTTON_NEGATIVE:
                        dialog.dismiss();
                        break;
                    case DialogInterface.BUTTON_POSITIVE:
                        dialog.dismiss();
                        
                        Dialog d = (Dialog) dialog;
                        EditText commentEntry = (EditText) d.findViewById(R.id.dialog_comment_entry);
                        String comment = commentEntry.getText().toString();
                        
                        if (TextUtils.isEmpty(comment.trim())) {
                            showDialog(DIALOG_EMPTY_COMMENT);
                            return;
                        }
                        
                        if (!HttpUtils.isConnectedToNetwork(BuzzDetailActivity.this)) {
                            showDialog(DIALOG_NO_NETWORK);
                            return;
                        }
                        
                        showDialog(DIALOG_POST_COMMENT);
                        
                        /* execute the async task to post a comment. */
                        PostCommentTask task = new PostCommentTask(BuzzDetailActivity.this);
                        task.execute(comment, mActivityId, mToken, mTokenSecret);
                        break;
                    default:
                        Log.d(Constants.LOG_TAG, "Weird button selection: " + which);
                    }
                }
            };
            
            DialogInterface.OnDismissListener dismissListener = new DialogInterface.OnDismissListener() {
                public void onDismiss(DialogInterface dialog) {
                    Dialog d = (Dialog) dialog;
                    EditText commentEntry = (EditText) d.findViewById(R.id.dialog_comment_entry);
                    commentEntry.setText("");
                }    
            };
            
            builder.setNegativeButton(R.string.cancel_button, dialogListener);
            builder.setPositiveButton(R.string.comment_button, dialogListener);
            Dialog d = builder.create();
            d.setOnDismissListener(dismissListener);
            
            return d;
        case DIALOG_POST_COMMENT:
            ProgressDialog dialog = new ProgressDialog(this);
    		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    		dialog.setMessage(getString(R.string.post_comment_label));
    		return dialog;
    	case DIALOG_NO_NETWORK:
    	    builder = new AlertDialog.Builder(this);
    	    builder.setTitle(getString(R.string.no_network_title));
    	    builder.setMessage(getString(R.string.no_network_message));
    	    builder.setNeutralButton(R.string.confirm_dialog, new DialogInterface.OnClickListener() {
    	        public void onClick(DialogInterface dialog, int which) {
    	            dialog.dismiss();
    	        } 
    	    });
    	    return builder.create();
    	case DIALOG_EMPTY_COMMENT:
    	    builder = new AlertDialog.Builder(this);
    	    builder.setTitle(getString(R.string.no_comment_title));
    	    builder.setMessage(getString(R.string.no_comment_text));
    	    builder.setNeutralButton(R.string.confirm_dialog, new DialogInterface.OnClickListener() {
    	        public void onClick(DialogInterface dialog, int which) {
    	            dialog.dismiss();
    	        }    
    	    });
    	    return builder.create();
    	case DIALOG_COMMENT_ERROR:
    	    builder = new AlertDialog.Builder(this);
    	    builder.setTitle(getString(R.string.comment_error_title));
    	    builder.setMessage(getString(R.string.comment_error_text));
    	    builder.setNeutralButton(R.string.confirm_dialog, new DialogInterface.OnClickListener() {
    	        public void onClick(DialogInterface dialog, int which) {
    	            dialog.dismiss();
    	        }
    	    });
    	    return builder.create();
    	case DIALOG_RESHARE_NOTE:
    	    builder = new AlertDialog.Builder(this);
            builder.setTitle(getString(R.string.dialog_reshare_title));
            
            View shareView = getLayoutInflater().inflate(R.layout.dialog_comment, null, false);
            
            EditText textField = (EditText) shareView.findViewById(R.id.dialog_comment_entry);
            textField.setHint(getString(R.string.note_optional));
            
            builder.setView(shareView);
            
            DialogInterface.OnClickListener clickListener = new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    switch (which) {
                    case DialogInterface.BUTTON_NEGATIVE:
                        dialog.dismiss();
                        break;
                    case DialogInterface.BUTTON_POSITIVE:
                        dialog.dismiss();
                        
                        Dialog d = (Dialog) dialog;
                        EditText commentEntry = (EditText) d.findViewById(R.id.dialog_comment_entry);
                        String comment = commentEntry.getText().toString();
                        
                        if (!HttpUtils.isConnectedToNetwork(BuzzDetailActivity.this)) {
                            showDialog(DIALOG_NO_NETWORK);
                            return;
                        }
                        
                        showDialog(DIALOG_POST_RESHARE);
                        
                        /* execute the async task to reshare */
                        ReshareTask task = new ReshareTask(BuzzDetailActivity.this);
                        task.execute(comment, mActivityId, mToken, mTokenSecret);
                        break;
                    default:
                        Log.d(Constants.LOG_TAG, "Weird button selection: " + which);
                    }
                }
            };
            
            DialogInterface.OnDismissListener cancelListener = new DialogInterface.OnDismissListener() {
                public void onDismiss(DialogInterface dialog) {
                    Dialog d = (Dialog) dialog;
                    EditText commentEntry = (EditText) d.findViewById(R.id.dialog_comment_entry);
                    commentEntry.setText("");
                }    
            };
            
            builder.setNegativeButton(R.string.cancel_button, clickListener);
            builder.setPositiveButton(R.string.reshare_button, clickListener);
            Dialog shareDialog = builder.create();
            shareDialog.setOnDismissListener(cancelListener);
            
            return shareDialog;
        case DIALOG_POST_RESHARE:
            ProgressDialog reshare = new ProgressDialog(this);
        	reshare.requestWindowFeature(Window.FEATURE_NO_TITLE);
        	reshare.setMessage(getString(R.string.post_reshare_label));
        	return reshare;
        case DIALOG_RESHARE_ERROR:
        	builder = new AlertDialog.Builder(this);
        	builder.setTitle(getString(R.string.reshare_error_title));
        	builder.setMessage(getString(R.string.reshare_error_text));
        	builder.setNeutralButton(R.string.confirm_dialog, new DialogInterface.OnClickListener() {
        	    public void onClick(DialogInterface dialog, int which) {
        	        dialog.dismiss();
        	    }
        	});
        	return builder.create();
        default:
            Log.e(Constants.LOG_TAG, "Unrecognized dialog request: " + id);
            return null;
        }
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.detail_menu, menu);
        
        return true;
    }
    
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        return super.onPrepareOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.like_item:
            ActivityLikeTask task = new ActivityLikeTask(mActivityId, mToken, mTokenSecret);
            task.execute(true);
            return true;
        case R.id.comment_item:
            showDialog(DIALOG_COMMENT);
            return true;
        case R.id.reshare_item:
            showDialog(DIALOG_RESHARE_NOTE);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    public void viewComments(View view) {
        Intent intent = new Intent(this, CommentListActivity.class);
        intent.putExtra("id", mActivityId);

        startActivity(intent);
    }
    
    protected void refreshComments() {

    }
    
    static class ImageDownloadTask extends AsyncTask<String, Void, Bitmap> {
        private final WeakReference<ImageView> mImageViewRef;
        
        public ImageDownloadTask(ImageView imageView) {
            mImageViewRef = new WeakReference<ImageView>(imageView);
        }
        
        @Override
        protected Bitmap doInBackground(String... params) {
            return ImageUtils.downloadBitmap(params[0]);
        }
        
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (isCancelled()) {
                bitmap = null;
            }
            
            if (bitmap == null) {
                return;
            }
            
            if (mImageViewRef != null) {
                ImageView imageView = mImageViewRef.get();
                
                if (imageView != null) {
                    Bitmap roundedImage = ImageUtils.roundBitmapCorners(bitmap, 15);
                    imageView.setImageBitmap(roundedImage);
                    imageView.setVisibility(ImageView.VISIBLE);
                }
            }
        }
    }
    
    static class GalleryDownloadTask extends AsyncTask<String[], Void, Bitmap[]> {
        private final WeakReference<Gallery> mGalleryRef;
        private final WeakReference<View> mHolderRef;
        
        public GalleryDownloadTask(Gallery view, View holder) {
            mGalleryRef = new WeakReference<Gallery>(view);
            mHolderRef = new WeakReference<View>(holder);
        }
        
        @Override
        protected Bitmap[] doInBackground(String[]... params) {
            String[] images = params[0];
            Bitmap[] bitmaps = new Bitmap[images.length];
            
            for (int i = 0; i < images.length; i++) {
                bitmaps[i] = ImageUtils.downloadBitmap(images[i]);
            }
            
            return bitmaps;
        }
        
        @Override
        protected void onPostExecute(Bitmap[] images) {
            Gallery gallery = mGalleryRef.get();
            
            GalleryAdapter adapter = new GalleryAdapter(gallery.getContext());
            adapter.setImages(images);

            if (gallery != null) {
                gallery.setAdapter(adapter);
                gallery.setVisibility(Gallery.VISIBLE);
            }

            View holder = mHolderRef.get();

            if (holder != null) {
                holder.setVisibility(View.VISIBLE);
            }
        }
    }
    
    static class ActivityLikeTask extends AsyncTask<Boolean, Void, Boolean> {
        private final WeakReference<String> mActivityIdRef;
        private final WeakReference<String> mTokenRef;
        private final WeakReference<String> mTokenSecretRef;
        
        public ActivityLikeTask(String activityId, String token, String tokenSecret) {
            mActivityIdRef = new WeakReference<String>(activityId);
            mTokenRef = new WeakReference<String>(token);
            mTokenSecretRef = new WeakReference<String>(tokenSecret);
        }
        
        @Override
        protected Boolean doInBackground(Boolean... params) {
            try {
                return BuzzUtils.setLikeActivity(params[0], mActivityIdRef.get(), mTokenRef.get(), mTokenSecretRef.get());
            } catch (Exception e) {
                Log.e(Constants.LOG_TAG, "Error setting like status: " + e.toString());
                return false;
            }
        }
        
        @Override
        protected void onPostExecute(Boolean status) {
            Log.d(Constants.LOG_TAG, "Done with task.");
        }
    }
    
    static class PostCommentTask extends AsyncTask<String, Void, Boolean> {
        private final WeakReference<BuzzDetailActivity> mActivityRef;
        
        public PostCommentTask(BuzzDetailActivity act) {
            mActivityRef = new WeakReference<BuzzDetailActivity>(act);
        }
        
        @Override
        protected Boolean doInBackground(String... params) {
            try {
                return BuzzUtils.postComment(params[0], params[1], params[2], params[3]);
            } catch (Exception e) {
                Log.e(Constants.LOG_TAG, "Error posting comment: " + e.toString());
                return false;
            }
        }
        
        @Override
        protected void onPostExecute(Boolean status) {
            BuzzDetailActivity act = mActivityRef.get();

            if (act == null) {
                return;
            }
            
            act.dismissDialog(BuzzDetailActivity.DIALOG_POST_COMMENT);
            
            if (status) {
                act.refreshComments();
            } else {
                act.showDialog(BuzzDetailActivity.DIALOG_COMMENT_ERROR);
            }
        }
    }
    
    class ReshareTask extends AsyncTask<String, Void, Boolean> {
        private final WeakReference<BuzzDetailActivity> mActivityRef;
        
        public ReshareTask(BuzzDetailActivity act) {
            mActivityRef = new WeakReference<BuzzDetailActivity>(act);
        }
        
        @Override
        protected Boolean doInBackground(String... params) {
            try {
                return BuzzUtils.reshareActivity(params[0], params[1], params[2], params[3]);
            } catch (Exception e) {
                Log.e(Constants.LOG_TAG, "Error resharing activity: " + e.toString());
                return false;
            }
        }
        
        @Override
        protected void onPostExecute(Boolean status) {
            BuzzDetailActivity act = mActivityRef.get();

            if (act == null) {
                return;
            }
            
            act.dismissDialog(BuzzDetailActivity.DIALOG_POST_RESHARE);
            
            if (!status) {
                act.showDialog(BuzzDetailActivity.DIALOG_RESHARE_ERROR);
            }
        }
    }
}
